package com.ml.mall.job.impl;

import com.ml.mall.job.IBaseJobService;
import com.ml.mall.job.pojo.ScheduleJobDTO;
import com.ml.mall.util.JobCreator;
import com.ml.mall.util.TriggerCreator;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @author kyyang
 * job 的创建，修改，暂停，查询正在执行的job等
 */
@Slf4j
@Service
public class BaseJobServiceImpl implements IBaseJobService {

    /**
     * 统一job trigger suffix
     */
    public static final String JOB_TRIGGER_NAME_SUFFIX = "_trigger";
    /**
     * 统一job trigger group suffix
     */
    public static final String JOB_TRIGGER_GROUP_SUFFIX = "_trigger_group";
    private ApplicationContext applicationContext;
    private SchedulerFactoryBean schedulerFactoryBean;

    public BaseJobServiceImpl(ApplicationContext applicationContext, SchedulerFactoryBean schedulerFactoryBean) {
        this.applicationContext = applicationContext;
        this.schedulerFactoryBean = schedulerFactoryBean;
    }

    @Override
    public void addJob(ScheduleJobDTO jobInfo) {
        addJob(jobInfo, false);
    }

    @Override
    public void addJob(ScheduleJobDTO jobInfo, boolean replace) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            JobDataMap jobDataMap = jobInfo.getJobDataMap();
            // 创建 trigger
            Trigger trigger;
            if (jobInfo.getCronJob()) {
                trigger = TriggerCreator.createCronTrigger(jobInfo.getJobName() + JOB_TRIGGER_NAME_SUFFIX, jobInfo.getJobGroup() + JOB_TRIGGER_GROUP_SUFFIX, new Date(), jobInfo.getCronExpression(),
                        SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
            } else {
                trigger = TriggerCreator.createSimpleTrigger(jobInfo.getJobName() + JOB_TRIGGER_NAME_SUFFIX, jobInfo.getJobGroup() + JOB_TRIGGER_GROUP_SUFFIX, new Date(), jobInfo.getRepeatTime(),
                        SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
            }
            JobDetail jobDetail = JobCreator.createJob(
                    (Class<? extends QuartzJobBean>) Class.forName(jobInfo.getJobClass()),
                    false, applicationContext,
                    jobInfo.getJobName(),
                    jobInfo.getJobGroup(), jobDataMap,jobInfo.getDesc());

            if (!scheduler.checkExists(jobDetail.getKey())) {
                scheduler.scheduleJob(jobDetail, trigger);
            } else {
                if (replace) {
                    log.info("scheduleNewJobRequest jobAlreadyExist  replace old");
                    deleteJob(jobInfo.getJobName(), jobInfo.getJobGroup());
                    scheduler.scheduleJob(jobDetail, trigger);
                } else {
                    log.info("scheduleNewJobRequest jobAlreadyExist not replace old");
                }
            }
        } catch (ClassNotFoundException e) {
            log.warn("Class Not Found - {}", jobInfo.getJobClass(), e);
        } catch (SchedulerException e) {
            log.warn(e.getMessage(), e);
        }
    }


    @Override
    public void triggerJob(String jobName, String jobGroup) {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            log.error("触发job失败,error信息:{}", e);
        }
    }


    @Override
    public void pauseJob(String jobName, String jobGroup) {
        // 暂停
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            log.error("暂定job失败,error信息:{}", e.getMessage());
        }
    }

    @Override
    public boolean jobTriggerExist(String jobName, String jobGroup) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            return scheduler.checkExists(TriggerKey.triggerKey(jobName + JOB_TRIGGER_NAME_SUFFIX, jobGroup + JOB_TRIGGER_GROUP_SUFFIX));
        } catch (SchedulerException e) {
            log.warn("check job jobName:{},jobGroup:{} trigger exist 出现异常:{}", jobName, jobGroup, e.getMessage());
        }
        return false;
    }

    @Override
    public void resumeJob(String jobName, String jobGroup) {
        // 恢复
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName + JOB_TRIGGER_NAME_SUFFIX, jobGroup + JOB_TRIGGER_GROUP_SUFFIX);
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey);
            // 暂停状态
            if (Trigger.TriggerState.PAUSED.equals(triggerState)) {
                scheduler.resumeJob(JobKey.jobKey(jobName, jobGroup));
            }
        } catch (SchedulerException e) {
            log.error("恢复job jobName:{},jobGroup:{}失败: {}", jobName, jobGroup, e.getUnderlyingException());
        }
    }

    @Override
    public boolean jobExist(String jobName, String jobGroup) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            return scheduler.checkExists(JobKey.jobKey(jobName, jobGroup));
        } catch (SchedulerException e) {
            log.warn("");
        }
        return false;
    }

    @Override
    public void deleteJob(String jobName, String jobGroup) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
        } catch (SchedulerException e) {
            log.warn("删除job失败:jobName:{},jobGroup:{}错误信息:{}", e.getMessage());
        }
    }

}
